/*
 * COPYRIGHT:	2010 Christopher Smith, licenced under the GNU GPL v2; see COPYING in the top level directory
 * PROJECT:		sdedit
 * FILE:		acleditor init.cpp
 * PURPOSE:		acl editor dialog initilization
 *				included as part of acleditor.cpp
 */

class AclEditorInit : public AclEditorEditPopup
{
	PCWSTR const *Headers;

protected:
	AclEditorInit(AclEditorInitParams const &Init) :
		Headers(Init.AclAndState.State & ACL_FLAG_LABEL_ACL ? LabelHeaders : Init.Headers),
		AclEditorEditPopup(Init)
	{
		SdState = Init.SdState;
		PreviousAclState = Init.AclAndState.State;
		Create(WS_EX_CONTROLPARENT | WS_EX_WINDOWEDGE, ClassName, Init.Title, WS_VISIBLE | WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_VSCROLL, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, Init.Parent, NULL, NULL, NULL);
	}

private:
	HWND CreateListBox(DWORD ExtraStyle, HWND Parent, LONG Index)
	{
		HWND wnd = RaiseOnWin32ErrorT(CreateWindow(L"LISTBOX", L"List", ExtraStyle | WS_TABSTOP | WS_CHILD | WS_BORDER | LBS_NOTIFY | WS_CLIPSIBLINGS, 0, 0, 0, 0, Parent, NULL, NULL, NULL));
		SetWindowLong(wnd, GWL_ID, Index);
		SendMessage(wnd, WM_SETFONT, (WPARAM)Prefs.Font, FALSE);
		return wnd;
	}

	void CreateColumns()
	{
		RtlZeroStruct(Columns);

		Columns[COL_TSTE_NAME].Wnd = CreateListBox(WS_VISIBLE, Wnd, COL_TSTE_NAME);
		Columns[COL_TSTE_NAME].Group = CgTrusteeName;
		Columns[COL_TSTE_NAME].WidthFraction = 150;
		
		Columns[COL_TSTE_SID].Wnd = CreateListBox(WS_VISIBLE, Wnd, COL_TSTE_SID);
		Columns[COL_TSTE_SID].Group = CgTrusteeSid;
		Columns[COL_TSTE_SID].WidthFraction = 270;

		Columns[COL_OBJ_TYPE].Wnd = CreateListBox(0, Wnd, COL_OBJ_TYPE);
		Columns[COL_OBJ_TYPE].Group = CgObjType;
		Columns[COL_OBJ_TYPE].WidthFraction = 120;

		Columns[COL_OBJ_INH_TYPE].Wnd = CreateListBox(0, Wnd, COL_OBJ_INH_TYPE);
		Columns[COL_OBJ_INH_TYPE].Group = CgObjInhType;
		Columns[COL_OBJ_INH_TYPE].WidthFraction = 65;

		Columns[COL_INH_SOURCE].Wnd = CreateListBox(0, Wnd, COL_INH_SOURCE);
		Columns[COL_INH_SOURCE].Group = CgInhSrc;
		Columns[COL_INH_SOURCE].WidthFraction = 80;
		
		Columns[COL_ACE_TYPE].Wnd = CreateListBox(WS_VISIBLE, Wnd, COL_ACE_TYPE);
		Columns[COL_ACE_TYPE].Width = 50;
		Columns[COL_ACE_TYPE].PostPadWidth = Prefs.PadWidth;
		Columns[COL_ACE_TYPE].Group = CgAceType;

		for(UCHAR i = COL_ACE_FLAGS; i <= COL_MAX_ACE; i++)
		{
			Columns[i].Wnd = CreateListBox(LBS_MULTIPLESEL, Wnd, i);
			Columns[i].Width = Prefs.BitColumnWidth;
		}

		for(UCHAR i = COL_ACE_FLAGS; i <= COL_ACE_FLAGS + 0x7; i++)
			Columns[i].Group = CgAceFlags;

		Columns[COL_ACE_FLAGS + 5].Group = CgExtra;

		Columns[COL_MAX_ACE_FLAGS].PostPadWidth = Prefs.PadWidth;

		for(UCHAR i = COL_GENERIC; i <= COL_GENERIC + 0x3; i++)
			Columns[i].Group = CgGeneric;

		for(UCHAR i = COL_STANDARD + 0x5; i <= COL_STANDARD + 0x7; i++)
			Columns[i].Group = CgExtra;

		for(UCHAR i = COL_STANDARD; i <= COL_STANDARD + 0x4; i++)
			Columns[i].Group = CgStandard;

		Columns[COL_SYSTEM].Group = CgExtra;

		for(UCHAR i = COL_SPECIFIC; i <= COL_MAX_SPECIFIC; i++)
			Columns[i].Group = CgExtra;

		for(UCHAR i = COL_RESERVE; i <= COL_RESERVE + 0x1; i++)
			Columns[i].Group = CgExtra;

		Columns[COL_MAX_ALLOWED].Group = CgExtra;
	}

	void SetHeaders(PCWSTR const headers[DESC_SPECIFIC_SIZE])
	{
		for(UCHAR i = COL_MIN; i <= COL_MAX; i++)
			Columns[i].OverheadLabel = DefaultColumnDescriptions[i];

		for(UCHAR i = COL_SPECIFIC; i <= COL_MAX_SPECIFIC; i++)
		{
			UCHAR j = i - COL_SPECIFIC;
			if(headers[j])
			{
				Columns[i].OverheadLabel = headers[j];
				Columns[i].Group = CgSpecific;
			}
			else
			{
				Columns[i].OverheadLabel = DefaultColumnDescriptions[i];
				Columns[i].Group = CgExtra;
			}
		}
	}

	void SetStartingVisibility(BOOLEAN Set, ColumnGroups Cg, ToolButtonIndex Tbi)
	{
		SetColumnGroupVisibibility(Cg, Set);
		SendMessage(Toolbar, TB_CHECKBUTTON, Tbi, MAKELONG(Set, 0));
	}

protected:
	virtual void Init() override
	{
		TopLabels = new TopLabel::WindowObject(Wnd, Columns, Prefs.Font);

		CreateColumns();

		SetColumnGroupVisibibility(CgAceType, TRUE);
		SetColumnGroupVisibibility(CgAceFlags, TRUE);

		SetHeaders(Headers);

		UINT_PTR ToolbarImgResource = Prefs.LargeIcons ? IDB_ACLTOOLBAR_LG : IDB_ACLTOOLBAR;
		int ButtonWidth = Prefs.LargeIcons ? 32 : 16;
		int ButtonHeight = Prefs.LargeIcons ? 30 : 15;

		Toolbar = RaiseOnWin32ErrorT(CreateToolbarEx(Wnd, WS_CHILD | WS_VISIBLE | TBSTYLE_TOOLTIPS | TBSTYLE_WRAPABLE, TOOLBAR_ID, TbCount, SdEditGModule, ToolbarImgResource, ToolButtons, RTL_NUMBER_OF(ToolButtons), ButtonWidth, ButtonHeight, ButtonWidth, ButtonHeight, sizeof(TBBUTTON)));

		if(!(SdState & SD_FLAG_OBJECT_SUPPORT))
		{
			SendMessage(Toolbar, TB_SETSTATE, TbShowObject, 0); //not enabled
			SendMessage(Toolbar, TB_SETSTATE, TbShowObjectInherit, 0); //not enabled
		}

		if(!(PreviousAclState & ACL_FLAG_MERGE_FULL_CTRL))
		{
			for(ULONG i = TbMergeStart; i <= TbMergeEnd; i++)
				SendMessage(Toolbar, TB_SETSTATE, i, 0); //not enabled
		}

		if(PreviousAclState & ACL_FLAG_MERGE_CANON_CTRL) //re-enable just these for canonical control
		{
			SendMessage(Toolbar, TB_SETSTATE, TbMergeInhLast, TBSTATE_ENABLED);
			SendMessage(Toolbar, TB_SETSTATE, TbMergeInhOnly, TBSTATE_ENABLED);
		}

		if(!(PreviousAclState & ACL_FLAG_DEFAULT_AVAILABLE))
			SendMessage(Toolbar, TB_SETSTATE, TbLoadDefault, 0); //not enabled

		SetStartingVisibility(Prefs.ShowSid, CgTrusteeSid, TbShowSid);

		if(PreviousAclState & ACL_FLAG_LABEL_ACL)
		{
			SetStartingVisibility(Prefs.ShowExtra, CgStandard, TbShowStandard);
			SetStartingVisibility(Prefs.ShowExtra, CgGeneric, TbShowGeneric);
		}
		else
		{
			SetStartingVisibility(Prefs.ShowStandard, CgStandard, TbShowStandard);
			SetStartingVisibility(Prefs.ShowGeneric, CgGeneric, TbShowGeneric);
		}

		SetStartingVisibility(Prefs.ShowSpecific, CgSpecific, TbShowSpecific);
		SetStartingVisibility(Prefs.ShowExtra, CgExtra, TbShowExtra);

		if(SdState & SD_FLAG_OBJECT_SUPPORT)
		{
			SetStartingVisibility(Prefs.ShowObject, CgObjType, TbShowObject);
			SetStartingVisibility(Prefs.ShowObjectInherit, CgObjInhType, TbShowObjectInherit);
		}

		if(PreviousAclState & ACL_FLAG_AUTO_INH_SOURCES)
			SetStartingVisibility(Prefs.ShowInhSource, CgInhSrc, TbShowInheritSource);
		else
			SendMessage(Toolbar, TB_SETSTATE, TbShowInheritSource, 0);

		if(!(PreviousAclState & ACL_FLAG_AUDITFLAG_SUPPORT))
		{
			ShowWindow(Columns[COL_ACE_AUDIT_SUCC].Wnd, SW_HIDE);
			Columns[COL_ACE_AUDIT_SUCC].Group = CgExtra;
			ShowWindow(Columns[COL_ACE_AUDIT_FAIL].Wnd, SW_HIDE);
			Columns[COL_ACE_AUDIT_FAIL].Group = CgExtra;

			Columns[COL_ACE_FLAGS + 4].PostPadWidth = Prefs.PadWidth; //now 4 is the last
		}

		if(SdState & SD_FLAG_NO_DELETE)
		{
			Columns[COL_STDDELETE].Group = CgExtra;
			ShowWindow(Columns[COL_STDDELETE].Wnd, SW_HIDE);
		}

		if(SdState & SD_FLAG_NO_SYNCHRONIZE)
		{
			Columns[COL_STDSYNCH].Group = CgExtra;
			ShowWindow(Columns[COL_STDSYNCH].Wnd, SW_HIDE);
		}

		if(SdState & SD_FLAG_CONTAINERS_ONLY)
		{
			Columns[COL_ACE_FLAG_OINH].Group = CgExtra;
			ShowWindow(Columns[COL_ACE_FLAG_OINH].Wnd, SW_HIDE);
		}

		ShowExtras = Prefs.ShowExtra;

		RefreshColumnSizes();

		__super::Init();
	}

	virtual LRESULT RecieveMessage(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam) override
	{
		if(msg == WM_SETFOCUS)
		{
			//pass focus along
			SetFocus(Columns[COL_TSTE_NAME].Wnd);
			return 0;
		}

		return __super::RecieveMessage(wnd, msg, wparam, lparam);
	}
};